home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr48 / asm32v20.zip / FLOAT.DOC < prev    next >
Text File  |  1994-06-24  |  13KB  |  516 lines

  1.  
  2. ***********************  FLOATING-POINT DATA  *******************************
  3.  
  4. ASM32 floating-point data subroutines (C) Copyright 1994 Douglas Herr
  5. all rights reserved
  6.  
  7. ASM32 recognizes two floating point formats: IEEE-standard single-
  8. precision, and IEEE-standard double-precision.  Single-precision
  9. floating point numbers are 4 bytes long, and are referred to as float4
  10. or simply f4, while double-precision floating point numbers are 8 bytes
  11. long, which I describe as float8 or f8.  This is the format used by the
  12. Intel 80x87 math coprocessors.
  13.  
  14.  
  15. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  16.  
  17. ABSF4:     absolute value of float4 number
  18. Source:    absf4.asm
  19.  
  20. Call with: DS:[EBX] pointing to 4-byte real number
  21. Returns:   number converted to absolute value
  22. Uses:      flags
  23.  
  24. Example:
  25.  
  26. include model.inc
  27.  
  28. extrn   absf4:near
  29.  
  30. include dataseg.inc
  31. f4      dd -123.456
  32. @curseg ends
  33.  
  34. include codeseg.inc
  35.         .
  36.         .
  37.         .
  38.         lea     ebx,f4           ; point to 4-byte real number
  39.         call    absf4            ; convert to absolute value
  40.  
  41.  
  42. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  43.  
  44. ABSF8:     absolute value of float8 number
  45. Source:    absf8.asm
  46.  
  47. Call with: DS:[EBX] pointing to 8-byte real number
  48. Returns:   number converted to absolute value
  49. Uses:      flags
  50.  
  51. Example:
  52.  
  53. include model.inc
  54.  
  55. extrn   absf8:near
  56.  
  57. include dataseg.inc
  58. f8      dd -123.456789
  59. @curseg ends
  60.  
  61. include codeseg.inc
  62.         .
  63.         .
  64.         .
  65.         lea     bx,f8            ; point to 8-byte real number
  66.         call    absf8            ; convert to absolute value
  67.  
  68. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  69.  
  70. ADDF4:     add two float4 numbers
  71. Source:    addf4.asm
  72.  
  73. 80x87 not required; no OS dependancies
  74.  
  75. Call with: DS:[ESI] pointing to number0, ES:[EDI] pointing to number1
  76.            both numbers must be float4 numbers in IEEE format
  77. Returns:   if CF = 0, number0 is replaced by the sum
  78.            if CF = 1, the sum would result in an overflow or underflow;
  79.               neither number is changed
  80. Uses:      flags
  81.  
  82. Example:
  83.  
  84. include model.inc
  85.  
  86. extrn addf4:near
  87.  
  88. include dataseg.inc
  89. number0 dd 123.456
  90. number1 dd -67.4
  91.  
  92. include codeseg.inc
  93.          .
  94.          .
  95.          .
  96.         push    ds
  97.         pop     es           ; ES = DS
  98.         lea     esi,number0
  99.         lea     edi,number1
  100.         call    addf4
  101.  
  102. ; note that this can be used for subtraction by changing the sign
  103. ; of one of the numbers.
  104. ;
  105. ; changing the sign is trivial: if DS:[ESI] points to a float4 number,
  106. ; the sign is changed with
  107. ;
  108. ;      xor    byte ptr 3[esi],10000000b
  109.  
  110.  
  111. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  112.  
  113. ADDF8:     add two float8 numbers
  114. Source:    addf8.asm
  115.  
  116. 80x87 not required; no OS dependancies
  117.  
  118. Call with: DS:[ESI] pointing to number0, ES:[EDI] pointing to number1
  119.            both numbers must be float8 numbers in IEEE format
  120. Returns:   if CF = 0, number0 is replaced by the sum
  121.            if CF = 1, the sum would result in an overflow or underflow;
  122.               neither number is changed
  123. Uses:      CF
  124.  
  125. Example:
  126.  
  127. include model.inc
  128.  
  129. extrn addf8:near
  130.  
  131. include dataseg.inc
  132. number0 dq 123.456e16
  133. number1 dq -67.407865
  134.  
  135. include codeseg.inc
  136.          .
  137.          .
  138.          .
  139.         push    ds
  140.         pop     es           ; ES = DS
  141.         lea     esi,number0
  142.         lea     edi,number1
  143.         call    addf4
  144.  
  145. ; note that this can be used for subtraction by changing the sign
  146. ; of one of the numbers.
  147. ;
  148. ; changing the sign is trivial: if DS:[ESI] points to a float8 number,
  149. ; the sign is changed with
  150. ;
  151. ;      xor    byte ptr 7[esi],10000000b
  152.  
  153.  
  154. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  155.  
  156. CMPF4:      compare two float4 numbers
  157. Source:     cmpf4.asm
  158.  
  159. CMPF8:      compare two float8 numbers
  160. Source:     cmpf8.asm
  161.  
  162. 80x87 NOT required
  163.  
  164. Call with:  ESI pointing to number 0
  165.             EDI pointing to number 1
  166. Returns:    if ZF = 1, numbers are equal
  167.             if SF = 1, number 1 is larger
  168. Uses:       zero flag (ZF), sign flag (SF)
  169. Example:
  170.  
  171. extrn   cmpf4:near
  172.  
  173.  
  174. include dataseg.inc
  175.  
  176. v0      dd 12.345
  177. v1      dd 17.04
  178.  
  179. @curseg ends
  180.  
  181. include codeseg.inc
  182.  
  183.          .
  184.          .
  185.          .
  186.         lea    esi,v0            ; point ESI to number 0
  187.         lea    edi,v1            ; point EDI to number 1
  188.         call   cmpf4             ; compare
  189.         js     number1           ; v1 is larger if SF = 1
  190.         je     equal             ; numbers identical if ZF = 1
  191.                                   ; otherwise v0 is larger
  192.  
  193.  
  194. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  195.  
  196. F4TOI2:     copies the integer portion of a float4 number to AX
  197. Source:     f4toi2.asm
  198.  
  199. 80x87 not required
  200.  
  201. Note:       only the integer portion of the number is converted; decimals
  202.             are truncated
  203. Call with:  ESI pointing to a float4 number
  204. Returns:    if CF = 0, AX = integer number
  205.             if CF = 1, float4 number is too large (if positive)
  206.                        or is too small (if negtive)
  207. Uses:       AX, CF; all other flags and registers are saved
  208. Example:
  209.  
  210.  
  211. extrn   f4toi2:near
  212.  
  213. include dataseg.inc
  214.  
  215. float4  dd  1234.567
  216.  
  217. @curseg ends
  218.  
  219. include codeseg.inc
  220.  
  221.         .
  222.         .
  223.         .
  224.         lea  esi,float4
  225.         call f4toi2
  226.         jc   oops                     ; gotta fix something if error
  227.  
  228.  
  229.  
  230. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  231.  
  232. F4TOI4:     copies the long integer portion of a float4 number to EAX
  233. Source:     f4toi4.asm
  234.  
  235. 80x87 not required
  236.  
  237. Note:       only the integer portion of the number is converted; decimals
  238.             are truncated
  239. Call with:  ESI pointing to a float4 number
  240. Returns:    if CF = 0, EAX = long integer number
  241.             if CF = 1, float4 number is too large (if positive)
  242.                        or is too small (if negtive)
  243. Uses:       EAX, CF; all other flags and registers are saved
  244. Example:
  245.  
  246. extrn   f4toi4:near
  247.  
  248. include dataseg.inc
  249.  
  250. float4  dd  1234.567
  251.  
  252. @curseg ends
  253.  
  254. include codeseg.inc
  255.         .
  256.         .
  257.         .
  258.         lea    esi,float4
  259.         call   f4toi4
  260.         jc     oops                   ; gotta fix something if error
  261.  
  262.  
  263.  
  264.  
  265. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  266.  
  267. I4TOF4:     convert 4-byte integer to float4 IEEE format
  268. Source:     i4tof4.asm
  269.  
  270. 80x87 not required
  271.  
  272. Call with:  DS:[EBX] pointing to 4-byte buffer for float4 number
  273.             EAX = signed integer number to convert
  274. Returns:    converted number in float4 IEEE format at DS:[EBX]
  275. Uses:       nothing; all registers and flags are saved
  276. Example:
  277.  
  278. include model.inc
  279.  
  280. extrn   i4tof4:near
  281.  
  282. include dataseg.inc
  283. float4  dd ?                          ; initial number undefined
  284. longint dd -123456789
  285.  
  286. include codeseg.inc
  287.         .
  288.         .
  289.         .
  290.         mov    eax,longint       ; signed integer
  291.         lea    ebx,float4        ; point to buffer for converted number
  292.         call   i4tof4
  293.  
  294.  
  295.  
  296. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  297.  
  298. MAXF4, MAXF4b: find maximum value in single-precision real-number array
  299. Source:        maxf4.asm
  300.  
  301. MINF4, MINF4b: find minimum value in single-precision real-number array
  302. Source:        minf4.asm
  303.  
  304. 80x87 not required
  305.  
  306. Call with:  EDI pointing to array element at start of search
  307.             ECX = number of array elements to search
  308.             For maxf4b or minf4b, call with EBX = byte increment between
  309.             array elements.  Maxf4 and minf4 assume byte increment = 4.
  310. Returns:    EAX = array element number with maximum or minimum value
  311.             note that the offset of that number is EDI + (EAX shl 2).
  312.             With maxf4b and minf4b, the offset of the number is
  313.             EDI + (EAX * EBX).  CF = 1 if called with ECX = 0.
  314. Uses:       EAX, CF
  315. Example:
  316.  
  317. extrn  maxf4:near
  318.  
  319. include dataseg.inc
  320.  
  321. floatdata   dd 1500 dup(0)
  322.  
  323. @curseg ends
  324.  
  325. include codeseg.inc
  326.  
  327. ; program provides values for the array
  328.        .
  329.        .
  330.        .
  331.        lea    edi,floatdata      ; EDI points to the data array
  332.        mov    ecx,1500           ; search entire array
  333.        call   maxf4              ; returns with EAX = array element
  334.  
  335.  
  336.  
  337. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  338.  
  339. MAXF8, MAXF8b: find maximum value in double-precision real-number array
  340. Source:        maxf8.asm
  341.  
  342. MINF8, MINF8b: find minimum value in double-precision real-number array
  343. Source:        minf8.asm
  344.  
  345. 80x87 not required
  346.  
  347. Call with:  EDI pointing to array element at start of search
  348.             ECX = number of array elements to search
  349.             For maxf8b or minf8b, call with EBX = byte increment between
  350.             array elements.  Maxf8 and minf8 assume byte increment = 8.
  351. Returns:    EAX = array element number with maximum or minimum value
  352.             note that the offset of that number is EDI + (EAX shl 3)
  353.             With maxf8b and minf8b, the offset of the number is
  354.             EDI + (EAX * EBX).  CF = 1 if called with ECX = 0.
  355. Uses:       EAX, CF
  356. Example:
  357.  
  358. extrn  maxf8:near
  359.  
  360. include dataseg.inc
  361.  
  362. floatdata   dq 1500 dup(0)
  363.  
  364. @curseg ends
  365.  
  366. include codeseg.inc
  367.  
  368. ; program provides values for the array
  369.        .
  370.        .
  371.        .
  372.        lea    edi,floatdata      ; EDI points to the data array
  373.        mov    ecx,1500           ; search entire array
  374.        call   maxf8              ; returns with EAX = array element
  375.        shl    eax,3
  376.        add    edi,eax            ; EDI points to maximum value
  377.  
  378.  
  379.  
  380. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  381.  
  382. MULF4:      multiplies two float4 numbers
  383. Source:     mulf4.asm
  384.  
  385. 80x87 not required
  386.  
  387. Call with:  DS:[ESI] pointing to number0, ES:[EDI] pointing to number1
  388. Returns:    if CF = 0, no error; product replaces number0 at DS:[ESI]
  389.             if CF = 1, the product is either zero or infinity (number0 is lost)
  390. Uses:       CF; all other flags and registers are saved
  391. Example:
  392.  
  393. include model.inc
  394.  
  395. extrn   mulf4:near
  396.  
  397. include dataseg.inc
  398. number0 dd 1.234
  399. number1 dd 0.5
  400. @curseg ends
  401.  
  402. include codeseg.inc
  403.          .
  404.          .
  405.          .
  406.          push   ds
  407.          pop    es
  408.          lea    esi,number0
  409.          lea    edi,number1
  410.          call   mulf4
  411.  
  412.  
  413. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  414.  
  415. SCALEF4:    scale a float4 number by an integer power of 2
  416. Source:     scalef4.asm
  417.  
  418. SCALEF8:    scale a float8 number by an integer power of 2
  419. Source:     scalef8.asm
  420.  
  421. 80x87 not required; no OS dependancies
  422.  
  423. Call with:  DS:[ESI] pointing to the float4 data
  424.             AL = scale factor (may be positive or negative)
  425. Returns:    CF = 0 if success: number was properly scaled
  426.             CF = 1 if error: resulting number would have overflowed
  427.                    number unchanged in this case
  428. Uses:       CF; all other flags and all registers saved
  429. Example:
  430.  
  431. include model.inc
  432.  
  433. include codeseg.inc
  434.         .
  435.         .
  436.         .
  437.         lea   esi,float4data
  438.         mov   al,3             ; scale by (2^3) effectively multiplies by 8
  439.         call  scalef4
  440.         jc    oops             ; take remedial action if error
  441.  
  442.  
  443. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  444.  
  445. SORTF4HI:    sort an array of single-precision real numbers, highest first
  446. Source:      sortf4hi.asm
  447.  
  448. SORTF4LO:    sort an array of single-precision real numbers, lowest first
  449. Source:      sortf4lo.asm
  450.  
  451. 80x87 not required
  452.  
  453. Call with:  ES:[EDI] pointing to the first of the array elements to be
  454.             sorted, ECX = number of array elements
  455. Returns:    nothing
  456. Uses:       nothing; all registers and flags are saved
  457. Example:
  458.  
  459. extrn   sortf4hi:near
  460.  
  461. include dataseg.inc
  462.  
  463. floatdata   dd 1500 dup(0)
  464.  
  465. @curseg    ends
  466.  
  467. include codeseg.inc
  468.  
  469. ; program provides values for the array
  470.         .
  471.         .
  472.         lea     edi,floatdata
  473.         push    ds
  474.         pop     es
  475.         mov     ecx,1500           ; sort entire array
  476.         call    sortf4hi           ; highest number first
  477.  
  478.  
  479.  
  480. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  481.  
  482. SORTF8HI:    sort an array of double-precision real numbers, highest first
  483. Source:      sortf8hi.asm
  484.  
  485. SORTF8LO:    sort an array of double-precision real numbers, lowest first
  486. Source:      sortf8lo.asm
  487.  
  488. 80x87 not required
  489.  
  490. Call with:  ES:[EDI] pointing to the first of the array elements to be
  491.             sorted, ECX = number of array elements
  492. Returns:    nothing
  493. Uses:       nothing; all registers and flags are saved
  494. Example:
  495.  
  496. extrn   sortf8hi:near
  497.  
  498. include dataseg.inc
  499.  
  500. floatdata   dq 1500 dup(?)
  501.  
  502. @curseg    ends
  503.  
  504. include codeseg.inc
  505.  
  506. ; program provides values for the array
  507.         .
  508.         .
  509.         lea     edi,floatdata
  510.         push    ds
  511.         pop     es
  512.         mov     ecx,1500           ; sort entire array
  513.         call    sortf8hi           ; highest value first
  514.  
  515.  
  516.